package org.xxpay.service.impl;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.xxpay.core.common.constant.MchConstant;
import org.xxpay.core.common.constant.RetEnum;
import org.xxpay.core.common.exception.ServiceException;
import org.xxpay.core.common.util.BtUtil;
import org.xxpay.core.common.util.JsonUtil;
import org.xxpay.core.entity.SysLoginFailIpRecord;
import org.xxpay.core.entity.SysLoginFailIpRecordExample;
import org.xxpay.core.service.ISysLoginFileIpRecordService;
import org.xxpay.service.dao.mapper.SysLoginFailIpRecordMapper;

import java.util.List;

/**
 * @author: pangxaioyu
 * @date: 20/11/12
 * @description:
 */
@Service
public class SysLoginFailIpRecordImpl implements ISysLoginFileIpRecordService {

    @Autowired
    private SysLoginFailIpRecordMapper recordMapper;

    @Override
    public SysLoginFailIpRecord findById(String ip) {
        return recordMapper.selectByPrimaryKey(ip);
    }

    @Override
    public List<SysLoginFailIpRecord> find(SysLoginFailIpRecord record) {
        SysLoginFailIpRecordExample example = new SysLoginFailIpRecordExample();
        example.setOrderByClause("createTime DESC");
        SysLoginFailIpRecordExample.Criteria criteria = example.createCriteria();
        setCriteria(criteria, record);
        return recordMapper.selectByExample(example);
    }

    @Override
    public int add(SysLoginFailIpRecord record) {
        return recordMapper.insertSelective(record);
    }

    @Override
    public int update(SysLoginFailIpRecord record) {
        return recordMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public int delete(String ip) {
        return recordMapper.deleteByPrimaryKey(ip);
    }

    @Override
    public int failCountByIp(String ip, String btSignConfig, String btUrlConfig, Integer loginCountConfig, Byte loginToBlackType, String userName) {

        SysLoginFailIpRecord record = findById(ip);
        if (record == null) {// 为空初次登录新增到表
            SysLoginFailIpRecord ipRecord = new SysLoginFailIpRecord();
            ipRecord.setIp(ip);
            ipRecord.setFailCount(1);
            ipRecord.setLoginToBlackType(loginToBlackType);
            ipRecord.setRemark("用户名：["+ userName + "] 已1次登录失败; 当前配置次数上限为 ["+loginCountConfig+"] 次");
            recordMapper.insertSelective(ipRecord);
            return loginCountConfig - 1;
        }else {
            if (record.getFailCount() > loginCountConfig) {
                // 次数为0 并且拉黑类型为是 添加到宝塔屏蔽IP
                if (loginToBlackType == MchConstant.LOGIN_TO_BLACK_BT) {
                    addToBt(btSignConfig, btUrlConfig, record.getIp(), userName);
                }
                return 0;
            }
            // 小于屏蔽次数累加，返回剩余可尝试次数
            Integer count = record.getFailCount() + 1;
            record.setFailCount(count);
            // 拉黑类型为否返回0
            record.setRemark("用户名：["+ userName + "] 已" + count + "次登录失败; 当前配置次数上限为 ["+loginCountConfig+"] 次");
            recordMapper.updateByPrimaryKeySelective(record);
            // 剩余可尝试次数
            Integer value = loginCountConfig - record.getFailCount();
            // 次数为0 并且拉黑类型为是 添加到宝塔屏蔽IP
            if (value < 0 && loginToBlackType == MchConstant.LOGIN_TO_BLACK_BT) {
                addToBt(btSignConfig, btUrlConfig, record.getIp(), userName);
            }
            return value;
        }
    }

    public void addToBt(String btSignConfig, String btUrlConfig, String ip, String userName) {
        // 添加到宝塔屏蔽IP
        JSONObject json = JsonUtil.getJSONObjectFromJson(BtUtil.addShieldIp(btSignConfig, btUrlConfig, ip, userName + "登陆次数超限"));
        if (!json.getBoolean("status")) {
            throw new ServiceException(RetEnum.RET_MGR_BT_ADD_IP_FAIL, json.getString("msg"));
        }
        // 移除db中的ip
        delete(ip);
    }

    void setCriteria(SysLoginFailIpRecordExample.Criteria criteria, SysLoginFailIpRecord record) {
        if(record != null) {
            if(StringUtils.isNotEmpty(record.getIp())) criteria.andIpEqualTo(record.getIp());
            if(record.getFailCount() != null) criteria.andFailCountEqualTo(record.getFailCount());
            if (record.getLoginToBlackType() != null) criteria.andLoginToBlackTypeEqualTo(record.getLoginToBlackType());
        }
    }
}
